package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tanhua.dubbo.api.db.TestSoulApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.model.db.*;
import com.tanhua.model.db.TestCharacter;
import com.tanhua.model.vo.OptionsVo;
import com.tanhua.model.vo.QuestionsVo;
import com.tanhua.model.vo.TestResultVo;
import com.tanhua.model.vo.TestSoulVo;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service
public class TestSoulService {

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private TestSoulApi testSoulApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public List<TestSoulVo> getTestSoul() {
        String key = "USER_TESTED_" + UserHolder.getUserId();
        List<Integer> ids = new ArrayList<>();
        //判断用户是否做过问卷调查
        if (stringRedisTemplate.hasKey(key)) {
            Set<String> members = stringRedisTemplate.opsForSet().members(key);
            for (String member : members) {
                ids.add(Integer.parseInt(member));
            }
        }
        //查询问卷列表
        List<TestSoul> testSoul = testSoulApi.getTestSoul();
        List<TestSoulVo> voList = new ArrayList<>();
        List<QuestionsVo> queryVo = new ArrayList<>();

        for (TestSoul soul : testSoul) {

            //查询题目列表
            List<Questions> questionsList = testSoulApi.getQuestions(soul.getId());
            for (Questions questions : questionsList) {
                //查询选项列表
                List<Options> optionsList = testSoulApi.getOptions(questions.getId());
                List<OptionsVo> optionsVoList = OptionsVo.init(optionsList);
                QuestionsVo questionsVo = QuestionsVo.init(questions, optionsVoList);
                queryVo.add(questionsVo);

            }
            TestSoulVo init = TestSoulVo.init(soul, queryVo);
            //判断ids是否为空
            if (CollectionUtil.isNotEmpty(ids)){
                for (Integer id : ids) {
                    //如果已经做过这个等级的测试就解锁下一级
                    if (id == soul.getId().intValue() || id == soul.getId() -1) {
                        init.setIsLock(0);
                    }
                    //如果做过测试就显示查看结果
                    if (id == soul.getId().intValue()){
                        init.setReportId("1");
                    }
                }
            }
            //封装vo
            voList.add(init);
            //清除上一等级的数据
            queryVo = new ArrayList<>();
        }

        return voList;
    }

    /**
     *      保存测试结果
     * @param answers
     * @return
     */
    public String answers(Map<String, List> answers) {
        List<Map<String,String>> list = answers.get("answers");
        List<Integer> questionId = new ArrayList<>();
        List<Integer> optionId = new ArrayList<>();
        TestResult result = new TestResult();
        for (Map<String, String> map : list) {
            questionId.add(Integer.valueOf(map.get("questionId")));
            optionId.add(Integer.valueOf(map.get("optionId")));
        }
        Integer optionScore = 0;          //用户分数
        Integer userReason = 0;          //理性
        Integer userIsabstract = 0;      //抽象
        Integer userJudge = 0;           //判断
        Integer userExtroversion = 0;    //外向
        String testId = null;
        //获取各个维度总分及用户分数
        List<QuestionAndoptionsScore> questionAndoptionsScores = testSoulApi.sumByUserScore(questionId, optionId);
        for (QuestionAndoptionsScore score : questionAndoptionsScores) {
            optionScore += score.getOptionscore();
            switch (score.getSum()){
                case 1:
                    userExtroversion = (score.getOptionscore() * 100) / score.getQuestionscore();break;
                case 2 :
                    userReason = (score.getOptionscore() * 100) / score.getQuestionscore();break;
                case 3 :
                    userJudge = (score.getOptionscore() * 100) / score.getQuestionscore();break;
                case 4 :
                    userIsabstract = (score.getOptionscore() * 100) / score.getQuestionscore();break;
                default :break;
            }
        }
        //获取测试类型ID
        List<Questions> questionsList = testSoulApi.getQuestionByIds(questionId);
        for (Questions questions : questionsList) {
            testId = String.valueOf(questions.getTestSoulId());
            if (BeanUtil.isNotEmpty(testId)) {
                break;
            }
        }
        //按用户得分获取所属鉴定结果
        TestCharacter character = new TestCharacter();
        if (optionScore < 21){

            character = testSoulApi.getCharacter(20);

        }else if (optionScore > 20 && optionScore < 41) {

            character = testSoulApi.getCharacter(40);

        }else if (optionScore > 40 && optionScore <= 55) {

            character = testSoulApi.getCharacter(55);

        }else {

            character = testSoulApi.getCharacter(56);
        }
        //拼接百分比
        Map<String,String> map = new HashMap<>();
        //拼接百分号
        map.put("外向", userExtroversion + "%");
        map.put("判断", userJudge + "%");
        map.put("抽象", userIsabstract + "%");
        map.put("理性", userReason + "%");
        //封装数据
        result.setUserid(UserHolder.getUserId().intValue());
        result.setConclusion(character.getTbCharacter());
        result.setCover(character.getCover());
        result.setUserScore(optionScore);
        result.setTestCharacterId(character.getId());
        result.setTestSoulId(Integer.parseInt(testId));
        result.setItems(JSON.toJSONString(map));
        //存入数据库
        Integer id = testSoulApi.addResult(result,Long.parseLong(testId),UserHolder.getUserId());
        //存入缓存
        String key = "USER_TESTED_" + UserHolder.getUserId();
        stringRedisTemplate.opsForSet().add(key,testId);
        //返回结果ID
        return id.toString();
    }

    /**
     *      查看测试结果
     * @param id
     * @return
     */
    public TestResultVo getReport(Integer id) {

        //查询当前用户测试结果
        TestResult result = testSoulApi.getTestResult(id,UserHolder.getUserId());
        Map map = JSON.parseObject(result.getItems(), Map.class);
        Map<String,String> dimensions = new HashMap<>();
        List<Map<String,String>> mapList = new ArrayList<>();
        Set<String> set = map.keySet();
        for (String key : set) {
            dimensions.put("key",key);
            dimensions.put("value",map.get(key).toString());
            mapList.add(dimensions);
            dimensions = new HashMap<>();
        }
        // 根据分数查询相似用户Id
        Integer userScore = result.getUserScore();
        List<Integer> userIds = testSoulApi.getUserIdByScore(userScore,UserHolder.getUserId());
        // 查询用户详情
        List<Long> userIdsList = userIds.stream().map(Integer::longValue).collect(Collectors.toList());
        List<UserInfo> userInfoList = userInfoApi.getUsersByid(userIdsList);
        List<Map<String, Object>> similarYou = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userInfoList)) {
            for (UserInfo userInfo : userInfoList) {
                Map<String,Object> similarYouMap = new HashMap<>();
                similarYouMap.put("id",userInfo.getId().intValue());
                similarYouMap.put("avatar",userInfo.getAvatar());
                similarYou.add(similarYouMap);
            }
        }
        TestResultVo vo = new TestResultVo();
        vo.setConclusion(result.getConclusion());
        vo.setCover(result.getCover());
        vo.setDimensions(mapList);
        vo.setSimilarYou(similarYou);
        return vo;
    }
}
